package com.isoft.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeException;

import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

@MappedTypes(String.class)
public class DmDateTypeHandler extends BaseTypeHandler<String> {
    private static final DateTimeFormatter INPUT_FORMATTER =
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final DateTimeFormatter OUTPUT_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
                                    String parameter, JdbcType jdbcType) throws SQLException {
        try {
            if (isValidDmDate(parameter)) {
                LocalDateTime dateTime = LocalDateTime.parse(parameter, INPUT_FORMATTER);
                ps.setTimestamp(i, Timestamp.valueOf(dateTime));
            } else {
                ps.setNull(i, Types.TIMESTAMP);
            }
        } catch (DateTimeParseException e) {
            throw new TypeException("日期格式转换失败，要求格式：yyyyMMddHHmmss，实际值：" + parameter, e);
        }
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Timestamp timestamp = rs.getTimestamp(columnName);
        return formatTimestamp(timestamp);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Timestamp timestamp = rs.getTimestamp(columnIndex);
        return formatTimestamp(timestamp);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Timestamp timestamp = cs.getTimestamp(columnIndex);
        return formatTimestamp(timestamp);
    }

    private String formatTimestamp(Timestamp timestamp) {
        if (timestamp == null) {
            return null;
        }
        return timestamp.toLocalDateTime().format(INPUT_FORMATTER);
    }

    private boolean isValidDmDate(String dateStr) {
        if (dateStr == null || dateStr.length() != 14) {
            return false;
        }
        try {
            LocalDateTime.parse(dateStr, INPUT_FORMATTER);
            return true;
        } catch (DateTimeParseException e) {
            return false;
        }
    }
}